package cn.com.anypay.manager.miaoma.suantaiqrcode.handler.impl;

import cn.com.anypay.manager.miaoma.suantaiqrcode.SuantaiQrcodeEntity;
import cn.com.anypay.manager.miaoma.suantaiqrcode.handler.AbstractQrCodeHandler;
import cn.com.anypay.manager.miaoma.suantaiqrcode.dto.QrCodeGatewayResponse;
import cn.com.anypay.manager.common.response.ApiResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.qiniu.util.Hex;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * 小程序码处理器
 *
 * 处理小程序类型的二维码（类型7）
 * JSON结构: {"miniAppName": "小程序名称", "miniAppCodeImg": "图片URL"}
 */
@Slf4j
@Component
public class MiniProgramQrCodeHandler extends AbstractQrCodeHandler {

    private static final Integer SUPPORTED_TYPE = 7;
    private static final String HANDLER_NAME = "MiniProgramQrCodeHandler";

    @Value("${suantai.qrcode.secret-key}")
    private String secretKey;

    @Value("${suantai.qrcode.base-url}")
    private String baseUrl;

    @Override
    public ApiResponse<Object> handle(SuantaiQrcodeEntity qrcode, String id) {
        logHandleStart(id);

        if (!isValidContent(qrcode.getContent())) {
            logHandleComplete(id, "Content is empty");
            return createErrorResponse(HttpStatus.BAD_REQUEST, "Content is empty");
        }

        try {
            JsonNode content = parseJsonContent(qrcode.getContent());
            if (content == null) {
                logHandleComplete(id, "Invalid JSON content");
                return createErrorResponse(HttpStatus.BAD_REQUEST, "Invalid JSON content");
            }

            // 验证小程序码必需字段
            String miniAppName = extractMiniAppName(content);
            String miniAppCodeImg = extractMiniAppCodeImg(content);

            if (miniAppName == null || miniAppName.trim().isEmpty()) {
                logHandleComplete(id, "Missing miniAppName");
                return createErrorResponse(HttpStatus.BAD_REQUEST, "小程序名称不能为空");
            }

            if (miniAppCodeImg == null || miniAppCodeImg.trim().isEmpty()) {
                logHandleComplete(id, "Missing miniAppCodeImg");
                return createErrorResponse(HttpStatus.BAD_REQUEST, "小程序码图片不能为空");
            }

            // 构建小程序码展示页面的跳转URL
            // 从baseUrl中提取域名部分，然后拼接正确的API路径
            String domain = baseUrl.substring(0, baseUrl.indexOf("/api"));
            String redirectUrl = String.format("%s/api/anon/miniapp/display-page?id=%s&sign=%s",
                domain, id, generateSignature(id));

            logHandleComplete(id, "Redirecting to mini program landing page: " + redirectUrl);
            return createRedirectResponse(redirectUrl);
        } catch (Exception e) {
            log.error("[{}] Error processing mini program QR code, id: {}", getHandlerName(), id, e);
            logHandleComplete(id, "Processing error: " + e.getMessage());
            return createErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "处理小程序码时发生错误");
        }
    }

    /**
     * 从JSON内容中提取小程序名称
     */
    private String extractMiniAppName(JsonNode content) {
        JsonNode nameNode = content.get("miniAppName");
        return nameNode != null ? nameNode.asText() : null;
    }

    /**
     * 从JSON内容中提取小程序码图片URL
     */
    private String extractMiniAppCodeImg(JsonNode content) {
        JsonNode imgNode = content.get("miniAppCodeImg");
        return imgNode != null ? imgNode.asText() : null;
    }

    /**
     * 生成签名（简化实现，实际应该与Controller中的逻辑一致）
     */
    private String generateSignature(String id) {
        try {
            String dataToSign = String.format("id=%s", id);
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            return Hex.encodeHexString(sha256_HMAC.doFinal(dataToSign.getBytes("UTF-8")));
        } catch (Exception e) {
            log.error("Failed to generate signature for id: {}", id, e);
            throw new RuntimeException("签名生成失败", e);
        }
    }

    @Override
    public Integer getSupportedType() {
        return SUPPORTED_TYPE;
    }

    @Override
    public String getHandlerName() {
        return HANDLER_NAME;
    }

    @Override
    public ApiResponse<Object> handleForGateway(SuantaiQrcodeEntity qrcode, String id) {
        logHandleStart(id);

        if (!isValidContent(qrcode.getContent())) {
            logHandleComplete(id, "Content is empty");
            return createErrorResponse(HttpStatus.BAD_REQUEST, "Content is empty");
        }

        try {
            JsonNode content = parseJsonContent(qrcode.getContent());
            if (content == null) {
                logHandleComplete(id, "Invalid JSON content");
                return createErrorResponse(HttpStatus.BAD_REQUEST, "Invalid JSON content");
            }

            // 验证小程序码必需字段
            String miniAppName = extractMiniAppName(content);
            String miniAppCodeImg = extractMiniAppCodeImg(content);

            if (miniAppName == null || miniAppName.trim().isEmpty()) {
                logHandleComplete(id, "Missing miniAppName");
                return createErrorResponse(HttpStatus.BAD_REQUEST, "小程序名称不能为空");
            }

            if (miniAppCodeImg == null || miniAppCodeImg.trim().isEmpty()) {
                logHandleComplete(id, "Missing miniAppCodeImg");
                return createErrorResponse(HttpStatus.BAD_REQUEST, "小程序码图片不能为空");
            }

            // 为网关模式返回结构化数据
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("miniAppName", miniAppName);

            logHandleComplete(id, "Preparing mini program display data for gateway");
            return createGatewayDisplayResponse(
                qrcode.getQrCodeId(),
                qrcode.getQrCodeName(),
                qrcode.getQrCodeType(),
                QrCodeGatewayResponse.DisplayType.MINI_PROGRAM,
                miniAppCodeImg,
                miniAppName,
                "请使用微信扫描上方小程序码",
                metadata
            );
        } catch (Exception e) {
            log.error("[{}] Error processing mini program QR code for gateway, id: {}", getHandlerName(), id, e);
            logHandleComplete(id, "Processing error: " + e.getMessage());
            return createErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "处理小程序码时发生错误");
        }
    }
}